package com.cq.hd.product.processor;

import com.cq.hd.common.enums.biz.*;
import com.cq.hd.member.api.TbAppUserApi;
import com.cq.hd.member.api.TbBusinessAgentApi;
import com.cq.hd.member.api.TbBusinessApi;
import com.cq.hd.member.api.TbConfigSettingApi;
import com.cq.hd.member.api.vo.AppUserVo;
import com.cq.hd.member.api.vo.BusinessPageVo;
import com.cq.hd.product.api.dto.ActiveShareRewardDto;
import com.cq.hd.product.api.vo.ActiveDetailsVo;
import com.cq.hd.product.api.vo.ActiveShareRecordVo;
import com.cq.hd.product.api.vo.ActiveShareRewardVo;
import com.cq.hd.product.mapper.TbActiveAgentMapper;
import com.cq.hd.product.mapper.TbActiveShareMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

/**
 * @author much
 * @since 2024/11/01 16:53
 */
@Component
public class ActiveShareRewardProcessor {

    @Resource
    private TbBusinessAgentApi businessAgentApi;
    @Resource
    private TbBusinessApi businessApi;
    @Resource
    private TbAppUserApi appUserApi;
    @Resource
    private TbConfigSettingApi configSettingApi;
    @Resource
    private TbActiveShareMapper activeShareMapper;
    @Resource
    private TbActiveAgentMapper activeAgentMapper;

    public void process(ActiveShareRewardDto activeShareRewardDto) {
        Long loginUserId = activeShareRewardDto.getLoginUserId();
        ActiveDetailsVo activeDetailsVo = activeShareRewardDto.getActiveDetailsVo();
        // 用户没有登录
        if (loginUserId == null) {
            return;
        }
        // 用户不存在
        AppUserVo appUserVo = appUserApi.getById(loginUserId).unpack();
        if (appUserVo == null) {
            return;
        }
        // 分销开启状态(1-关闭，2-开启)
        if (!AgentStateEnum.OPEN.getValue().equals(activeDetailsVo.getAgentState())) {
            return;
        }
        // 判断是否商家自己查看活动，如果是则佣金展示和一级经纪人一样
        BusinessPageVo business = businessApi.getByUserId(loginUserId).unpack();
        if (business != null && business.getId().equals(activeDetailsVo.getBusinessId())) {
            return;
        }

        // 是经纪人
        if (appUserVo.getAgentState().equals(AgentStateEnum.OPEN.getValue())) {
            setActiveShareRewardForAgent(activeShareRewardDto, appUserVo);
        } else {
            setActiveShareRewardForNormalUser(activeShareRewardDto, appUserVo);
        }
    }

    private BigDecimal getActivePrice(ActiveDetailsVo activeDetailsVo) {
        BigDecimal activePrice = activeDetailsVo.getActivePrice();
        if (activeDetailsVo.getActiveGroupBuy() != null) {
            activePrice = activeDetailsVo.getActiveGroupBuy().getGroupBuyPrice();
        }
        return activePrice;
    }

    // 普通用户展示的佣金
    private void setActiveShareRewardForNormalUser(ActiveShareRewardDto activeShareRewardDto, AppUserVo appUserVo) {
        String shareCode = activeShareRewardDto.getShareCode();
        if (StringUtils.isBlank(shareCode)) {
            return;
        }
        ActiveDetailsVo activeDetailsVo = activeShareRewardDto.getActiveDetailsVo();
        ActiveShareRecordVo activeShareRecordVo = activeShareMapper.getByCode(shareCode, activeDetailsVo.getId());
        // 无效的分享码
        if (activeShareRecordVo == null) {
            return;
        }
        // 如果是二级分享的，则普通用户不显示分享赚
        if (activeShareRecordVo.getAgent2Id() != null && activeShareRecordVo.getAgent2Id() > 0) {
            return;
        }

        // 一级经纪人跟商家的佣金比例, 小于0表示不是绑定关系
        Long businessId = activeDetailsVo.getBusinessId();
        Long agent1Id = activeShareRecordVo.getAgent1Id();
        activeShareRewardDto.setAgent1Id(agent1Id);

        BigDecimal commissionRate = businessAgentApi.getAgentCommissionRate(agent1Id, businessId).unpack();
        if (commissionRate == null || commissionRate.compareTo(BigDecimal.ZERO) < 0) {
            return;
        }

        ActiveShareRewardVo activeShareRewardVo = new ActiveShareRewardVo();
        activeShareRewardVo.setAgentState(0); // 当前用户不是经纪人
        activeShareRewardVo.setAgentApplyPageType(2);

        if (RewardTypeEnum.COMMISSION.getValue().equals(activeDetailsVo.getRewardType())) {
            setCommission(activeShareRewardDto, activeShareRewardVo, commissionRate);
        } else {
            setPoints(activeShareRewardDto, activeShareRewardVo);
        }

        // 设置一级经纪人信息
        ActiveShareRewardVo.AgentInfo level1Agent = new ActiveShareRewardVo.AgentInfo();
        AppUserVo level1AgentUserVo = appUserApi.getById(agent1Id).unpack();
        level1Agent.setAgentUserId(agent1Id);
        level1Agent.setInviteCode(level1AgentUserVo.getInviteCode());
        level1Agent.setAgentAvatar(level1AgentUserVo.getAvatar());
        level1Agent.setAgentNickName(level1AgentUserVo.getNickName());
        activeShareRewardVo.setLevel1Agent(level1Agent);
    }

    private void setActiveShareRewardForAgent(ActiveShareRewardDto activeShareRewardDto, AppUserVo userVo) {
        ActiveDetailsVo activeDetailsVo = activeShareRewardDto.getActiveDetailsVo();
        // 设置agent1, agent2
        setAgentIds(activeShareRewardDto, userVo);

        Long businessId = activeDetailsVo.getBusinessId();
        Long agent1Id = activeShareRewardDto.getAgent1Id();
        // 是否是所有经纪人可推广：1-是，2-否
        if (AgentNumStateEnum.NO.getValue().equals(activeDetailsVo.getAgentNumState())) {
            // 如果不是商家的所有经纪人可推广，则判断当前用户是否是该活动所关联的经纪人
            List<Long> activeAgentList = activeAgentMapper.listByActiveId(activeDetailsVo.getId());
            if (CollectionUtils.isEmpty(activeAgentList) || !activeAgentList.contains(agent1Id)) {
                return;
            }
        }

        // 一级经纪人跟商家的佣金比例, 小于0表示不是绑定关系
        BigDecimal commissionRate = businessAgentApi.getAgentCommissionRate(agent1Id, businessId).unpack();
        if (commissionRate == null || commissionRate.compareTo(BigDecimal.ZERO) < 0) {
            // 经纪人和商家不是绑定关系，看当前用户是否一级经纪人
            if (userVo.getAgentLevel() != 1) {
                return;
            }
            ActiveShareRewardVo activeShareRewardVo = new ActiveShareRewardVo();
            activeShareRewardVo.setAgentState(1);
            activeShareRewardVo.setAgentApplyPageType(1); // 跳转一级经纪人申请
            // 设置商家信息
            ActiveShareRewardVo.BusinessInfo businessInfo = new ActiveShareRewardVo.BusinessInfo();
            BusinessPageVo businessPageVo = businessApi.getById(activeDetailsVo.getBusinessId()).unpack();
            businessInfo.setBusinessId(businessPageVo.getId());
            businessInfo.setBusinessShortName(businessPageVo.getBusinessShortName());
            businessInfo.setBusinessAvatar(businessPageVo.getLogo());
            activeShareRewardVo.setBusinessInfo(businessInfo);
            // 分享赚金额
            if (RewardTypeEnum.COMMISSION.getValue().equals(activeDetailsVo.getRewardType())) {
                setCommission(activeShareRewardDto, activeShareRewardVo, BigDecimal.ZERO);
            } else {
                setPoints(activeShareRewardDto, activeShareRewardVo);
            }

        } else {
            ActiveShareRewardVo activeShareRewardVo = new ActiveShareRewardVo();
            activeShareRewardVo.setAgentState(1);
            if (RewardTypeEnum.COMMISSION.getValue().equals(activeDetailsVo.getRewardType())) {
                setCommission(activeShareRewardDto, activeShareRewardVo, commissionRate);
            } else {
                setPoints(activeShareRewardDto, activeShareRewardVo);
            }
        }
    }

    private void setCommission(ActiveShareRewardDto activeShareRewardDto, ActiveShareRewardVo activeShareRewardVo, BigDecimal commissionRate) {
        ActiveDetailsVo activeDetailsVo = activeShareRewardDto.getActiveDetailsVo();
        if (activeDetailsVo.getDefaultCommissionType().equals(DefaultCommissionTypeEnum.NULL.getValue())) {
            return;
        }

        activeShareRewardVo.setRewardType(RewardTypeEnum.COMMISSION.getValue());

        BigDecimal activePrice = getActivePrice(activeDetailsVo);
        // 如果分组佣金或者专属佣金大于0，就替换掉活动设置的佣金，否则使用活动的佣金
        BigDecimal actCommissionRate = activeDetailsVo.getCommissionRate();
        if (commissionRate.compareTo(BigDecimal.ZERO) > 0) {
            actCommissionRate = commissionRate;
            activeShareRewardVo.setCommissionRate(commissionRate);
        }

        if (actCommissionRate.compareTo(BigDecimal.ZERO) > 0) {
            BigDecimal actualCommissionAmt = activePrice.multiply(actCommissionRate).divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN);
            activeShareRewardVo.setCommissionAmt(actualCommissionAmt);
            activeDetailsVo.setDefaultCommissionType(DefaultCommissionTypeEnum.COMMISSION_RATE.getValue());
            activeDetailsVo.setActiveShareReward(activeShareRewardVo);
        }

        // 二级经纪人跟一级经纪人的佣金比例
        Long agent1Id = activeShareRewardDto.getAgent1Id();
        Long agent2Id = activeShareRewardDto.getAgent2Id();
        if (agent2Id != null && agent2Id > 0) {
            BigDecimal rate = businessAgentApi.getSubAgentCommissionRate(agent2Id, agent1Id).unpack();
            if (rate == null || rate.compareTo(BigDecimal.ZERO) == 0) {
                rate = getDefaultLevel2CommissionRate(agent1Id);
            } else if (rate.compareTo(BigDecimal.ZERO) < 0) {
                activeDetailsVo.setActiveShareReward(null);
                return;
            }
            calculateLevel2Commission(activeShareRewardVo, actCommissionRate, activeDetailsVo, rate);
        }
        // 如果当前用户不是经纪人 & 通过分享链接进来
        if (StringUtils.isNotBlank(activeShareRewardDto.getShareCode()) && activeShareRewardVo.getAgentState() == 0) {
            BigDecimal defaultLevel2CommissionRate = getDefaultLevel2CommissionRate(agent1Id);
            if (defaultLevel2CommissionRate == null) {
                return;
            }
            calculateLevel2Commission(activeShareRewardVo, actCommissionRate, activeDetailsVo, defaultLevel2CommissionRate);
        }
    }

    private void calculateLevel2Commission(ActiveShareRewardVo activeShareRewardVo, BigDecimal commissionRate, ActiveDetailsVo activeDetailsVo, BigDecimal defaultLevel2CommissionRate) {
        BigDecimal actualCommissionRate = commissionRate.multiply(defaultLevel2CommissionRate).divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN);
        BigDecimal actualCommissionAmt = activeShareRewardVo.getCommissionAmt()
                .multiply(defaultLevel2CommissionRate).divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN);
        activeShareRewardVo.setCommissionAmt(actualCommissionAmt);
        activeShareRewardVo.setCommissionRate(actualCommissionRate);
        activeDetailsVo.setActiveShareReward(activeShareRewardVo);
    }

    private BigDecimal getDefaultLevel2CommissionRate(Long userId) {
        String defaultLevel2CommissionRate = configSettingApi.getUserConfigValue(
                userId, ConfigSettingKeyEnum.DEFAULT_LEVEL2_COMMISSION_RATE.name()).unpack();
        if (defaultLevel2CommissionRate == null) {
            return null;
        }
        return new BigDecimal(defaultLevel2CommissionRate);
    }

    private void setPoints(ActiveShareRewardDto activeShareRewardDto, ActiveShareRewardVo activeShareRewardVo) {
        ActiveDetailsVo activeDetailsVo = activeShareRewardDto.getActiveDetailsVo();
        if (activeDetailsVo.getRewardPoints() == null || activeDetailsVo.getRewardPoints().compareTo(BigDecimal.ZERO) < 0) {
            return;
        }
        activeShareRewardVo.setRewardType(RewardTypeEnum.POINTS.getValue());
        activeShareRewardVo.setRewardPoints(activeDetailsVo.getRewardPoints());

        // 如果是二级
        Long agent1Id = activeShareRewardDto.getAgent1Id();
        Long agent2Id = activeShareRewardDto.getAgent2Id();
        if (agent1Id != null) {
            activeDetailsVo.setActiveShareReward(activeShareRewardVo);
        }
        if (agent2Id != null && agent2Id > 0) {
            BigDecimal rate = businessAgentApi.getSubAgentCommissionRate(agent2Id, agent1Id).unpack();
            if (rate == null || rate.compareTo(BigDecimal.ZERO) == 0) {
                rate = getDefaultLevel2CommissionRate(agent1Id);
            }
            if (rate == null || rate.compareTo(BigDecimal.ZERO) < 0) {
                return;
            }
            BigDecimal agent2Points = activeShareRewardVo.getRewardPoints()
                    .multiply(rate).divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN);
            activeShareRewardVo.setRewardPoints(agent2Points);
            activeDetailsVo.setActiveShareReward(activeShareRewardVo);
        }
        // 如果当前用户不是经纪人 & 通过分享链接进来
        if (StringUtils.isNotBlank(activeShareRewardDto.getShareCode()) && activeShareRewardVo.getAgentState() == 0) {
            BigDecimal defaultLevel2CommissionRate = getDefaultLevel2CommissionRate(agent1Id);
            if (defaultLevel2CommissionRate == null) {
                return;
            }
            BigDecimal agent2Points = activeShareRewardVo.getRewardPoints()
                    .multiply(defaultLevel2CommissionRate).divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN);
            activeShareRewardVo.setRewardPoints(agent2Points);
            activeDetailsVo.setActiveShareReward(activeShareRewardVo);
        }
    }

    private void setAgentIds(ActiveShareRewardDto activeShareRewardDto, AppUserVo appUserVo) {
        if (appUserVo.getAgentId() != null && appUserVo.getAgentId() > 0) {
            activeShareRewardDto.setAgent1Id(appUserVo.getAgentId());
            activeShareRewardDto.setAgent2Id(appUserVo.getId());
        } else {
            activeShareRewardDto.setAgent1Id(appUserVo.getId());
        }
    }

}
